import pymongo
import pandas as pd


# 行为权重体系（总和不需要为1，后面会归一化）
BEHAVIOR_WEIGHTS = {
    'click': 0.1,  # 点击
   'read': 2.0,  # 阅读（提高比重）
   'review': 2.5,  # 评论（提高比重）
    'note': 1.5,  # 笔记
    'like': 0.4,  # 点赞
   'share': 1.0,  # 分享
    'collect': 1.8  # 收藏（提高比重）
}


def get_top_50_hot_books(mongo_uri, db_name, collection_name):
    """从MongoDB的指定集合中获取前50的热门书籍"""
    client = pymongo.MongoClient(mongo_uri)
    db = client[db_name]
    collection = db[collection_name]

    # 将MongoDB中的数据读取到DataFrame中
    cursor = collection.find({}, {"_id": 0, "b_id": 1, "action": 1})
    df = pd.DataFrame(list(cursor))

    # 计算权重总和并归一化
    total_weight = sum(BEHAVIOR_WEIGHTS.values())
    normalized_weights = {k: v / total_weight for k, v in BEHAVIOR_WEIGHTS.items()}

    # 为每个行为添加权重得分
    df['weighted_score'] = df['action'].map(normalized_weights)

    # 按书籍ID分组，计算每本书的总得分
    book_scores = df.groupby('b_id')['weighted_score'].sum().reset_index()

    # 按总得分降序排序，取前50本热门书籍
    top_50_hot_books = book_scores.sort_values(by='weighted_score', ascending=False).head(50)

    return top_50_hot_books


def save_hot_books_to_mongo(hot_books, mongo_uri, db_name, target_collection_name):
    """将热门书籍数据保存到MongoDB的指定集合中"""
    client = pymongo.MongoClient(mongo_uri)
    db = client[db_name]
    target_collection = db[target_collection_name]

    # 将DataFrame转换为字典列表，以便插入MongoDB
    hot_books_dict = hot_books.to_dict(orient='records')

    try:
        target_collection.insert_many(hot_books_dict)
        print(f"成功插入 {len(hot_books_dict)} 条热门书籍数据到MongoDB的 {target_collection_name} 集合中")
    except Exception as e:
        print(f"插入MongoDB失败: {e}")


def main():
    mongo_uri = "mongodb://localhost:27017/"
    db_name = "test"
    logs_collection_name = "logs"
    hot_books_collection_name = "hot_books"

    # 获取前50热门书籍数据
    top_50_hot_books = get_top_50_hot_books(mongo_uri, db_name, logs_collection_name)

    # 保存到MongoDB
    save_hot_books_to_mongo(top_50_hot_books, mongo_uri, db_name, hot_books_collection_name)


if __name__ == "__main__":
    main()